

#include "jxos_public.h"
#include "kernel/jxos_malloc.h"
#include "lib/composite_key.h"

#if (JXOS_STD_APP_COMPOSITE_KEY_TASK_ENABLE == 1)

#define SENDER_NAME "ck_snd"
static uint8_t composite_key_msg_pipe_buff[COMPOSITE_KEY_MSG_BUFF_LEN];
static JXOS_MESSAGE_PIPE_HANDLE composite_key_msg_pipe;

static swtime_type composite_key_long_press_swt;

static uint8_t composite_key_bit_mark_buffer[((COMPOSITE_KEY_ALL_KEY_MUN-1)/8) + 1];
static BIT_MARK_STRUCT composite_key_mark;

static COMPOSITE_KEY_STRUCT composite_key_struct_list[COMPOSITE_KEY_STRUCT_MAX];
static uint8_t composite_key_long_press_time_list[COMPOSITE_KEY_STRUCT_MAX];
static uint8_t composite_key_struct_list_count = 0;
static JXOS_MALLOC_MEM_POOL_STRUCT composite_key_mem_pool;

static uint8_t composite_key_long_press_key_num;

static JXOS_MESSAGE_PIPE_HANDLE pc_key_msg_pipe;

COMPOSITE_KEY_HANDLE* std_app_composite_key_create(uint8_t* composite_key_list, uint8_t composite_key_list_len,
					uint16_t long_press_time)
{
    COMPOSITE_KEY_STRUCT* h;
    if(jxos_malloc_set_mem_pool(&composite_key_mem_pool) == 0){
		return 0;
    }

    h = jxos_malloc(sizeof(COMPOSITE_KEY_STRUCT));
    if(h != 0){
		if(composite_key_init(h, composite_key_list, composite_key_list_len) == 0){
			return 0;
		}
		composite_key_long_press_time_list[composite_key_struct_list_count] = long_press_time;
        composite_key_struct_list_count++;
    }
    return (JXOS_TASK_HANDLE)h;
}

static void composite_key_press_hadler(uint8_t key_num)
{
	uint8_t i;
	bit_mark_set(&composite_key_mark, key_num);
	for(i = 0; i < composite_key_struct_list_count; i++){
#if (COMPOSITE_KEY_IN_LIST_ORDER == 0)
		if(composite_key_press_handler(&(composite_key_struct_list[i]),
										&composite_key_mark) == 1){
#else
		if(composite_key_press_handler_in_order(&(composite_key_struct_list[i]),
										&composite_key_mark, key_num) == 1){
#endif
//			printf("m key %d\r\n", i);
			if(composite_key_long_press_time_list[i] != 0){
				sys_svc_software_timer_set_time(composite_key_long_press_swt,
												composite_key_long_press_time_list[i]*1000);
				sys_svc_software_timer_restart(composite_key_long_press_swt);
				composite_key_long_press_key_num = i;
			}
			else{
				sys_svc_software_timer_stop(composite_key_long_press_swt);
				jxos_message_pipe_send(composite_key_msg_pipe, SENDER_NAME,
									&i, 1);
			}
		}
	}
}

static void composite_key_release_hadler(uint8_t key_num)
{
	bit_mark_reset(&composite_key_mark, key_num);
	sys_svc_software_timer_stop(composite_key_long_press_swt);
}

static void std_app_composite_key_task(uint8_t task_id, void * parameter)
{
    char key_code;
    uint8_t len;

    if(sys_svc_software_timer_check_overtime(composite_key_long_press_swt) == 1){
		sys_svc_software_timer_stop(composite_key_long_press_swt);
		jxos_message_pipe_send(composite_key_msg_pipe, SENDER_NAME,
								&composite_key_long_press_key_num, 1);
    }

    if(pc_key_msg_pipe == 0){
		pc_key_msg_pipe = jxos_message_pipe_get_handle("pc_key_pipe");
		jxos_message_pipe_receiver_name_register(pc_key_msg_pipe, "recpck");
    }
    if(jxos_message_pipe_check_empty(pc_key_msg_pipe) == 0){
        if(jxos_message_pipe_receive(pc_key_msg_pipe, "recpck", &key_code, &len) == 1){
//            printf("\r\nrec key_code: %c\r\n", key_code);
            if((key_code >= '0')
				&&(key_code <= '9')){
				/*******************************************/
				//key_press
//				printf("key press: %d\r\n", key_code-'0');
				composite_key_press_hadler(key_code-'0');
				/*******************************************/
			}
            else if((key_code >= 'a')
				&&(key_code <= 'j')){
				/*******************************************/
				//key_release
//				printf("key release: %d\r\n", key_code-'a');
				composite_key_release_hadler(key_code-'a');
				/*******************************************/
            }
        }
    }
}

void std_app_composite_key_task_init(void)
{
	uint8_t i;
    composite_key_mem_pool.mem_pool = (void*)composite_key_struct_list;
    composite_key_mem_pool.len = sizeof(COMPOSITE_KEY_STRUCT)*COMPOSITE_KEY_STRUCT_MAX;
    composite_key_mem_pool.offset = 0;
    composite_key_struct_list_count = 0;
	for(i = 0; i < COMPOSITE_KEY_STRUCT_MAX; i++){
		composite_key_struct_list[i].key_list = 0;
		composite_key_struct_list[i].key_list_len = 0;
		composite_key_struct_list[i].counter = 0;
	}
	pc_key_msg_pipe = 0;

	bit_mark_init(&composite_key_mark, composite_key_bit_mark_buffer,
				((COMPOSITE_KEY_ALL_KEY_MUN-1)/8) + 1, COMPOSITE_KEY_ALL_KEY_MUN);

    jxos_task_create(std_app_composite_key_task, "cm_key", 0);

	composite_key_msg_pipe = jxos_message_pipe_create(composite_key_msg_pipe_buff, COMPOSITE_KEY_MSG_BUFF_LEN, 3, "cp_key_pipe");
    jxos_message_pipe_sender_name_register(composite_key_msg_pipe, SENDER_NAME);

	composite_key_long_press_swt = sys_svc_software_timer_new();
}

#endif
